home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
Timer.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
9KB
|
281 lines
/*
* @(#)Timer.java 1.20 98/06/08
*
* Copyright 1997, 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
package com.sun.java.swing;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import com.sun.java.swing.event.EventListenerList;
/**
* Object subclass that causes an action to occur at a predefined rate. For
* example, an animation object can use a Timer as the trigger for drawing its
* next frame. Each Timer has a list of ActionListeners and a delay (
* the time between <b>actionPerfomed()</b> calls). When
* delay milliseconds have passed, a Timer sends the <b>actionPerformed()</b>
* message to its listeners. This cycle repeats until
* <b>stop()</b> is called, or halts immediately if the Jimer is configured
* to send its message just once.<p>
* Using a Timer involves first creating it, then starting it using
* the <b>start()</b> method.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version 1.20 06/08/98
* @author unknown
*/
public class Timer implements Serializable
{
int initialDelay, delay;
boolean repeats = true, coalesce = true;
protected EventListenerList listenerList = new EventListenerList();
boolean eventQueued = false;
private static boolean logTimers;
Runnable doPostEvent = null;
// These fields are maintained by TimerQueue.
// eventQueued can also be reset by the TimerQueue, but will only ever
// happen in applet case when TimerQueues thread is destroyed.
long expirationTime;
Timer nextTimer;
boolean running;
/**
* Creates a Timer that will notify its listeners every
* <i>delay</i> milliseconds.
* @param delay The number of milliseconds between listener notification
* @param listener An initial listener
* @see #setInitialDelay
* @see #setRepeats
*/
public Timer(int delay, ActionListener listener) {
super();
this.delay = delay;
this.initialDelay = delay;
doPostEvent = new DoPostEvent();
addActionListener(listener);
}
/**
* DoPostEvent is a runnable class that fires actionEvents to
* the listeners on the EventDispatchThread, via invokeLater.
* @see #post
*/
class DoPostEvent implements Runnable, Serializable {
public void run() {
if (logTimers) {
System.out.println("Timer ringing: " + Timer.this);
}
if(eventQueued) {
fireActionPerformed(new ActionEvent(Timer.this, 0, null));
cancelEvent();
}
}
Timer getTimer() {
return Timer.this;
}
}
/**
* Adds an actionListener to the Timer
*/
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
/**
* Removes an ActionListener from the Timer.
*/
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
/*
* Notify all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
* @see EventListenerList
*/
protected void fireActionPerformed(ActionEvent e) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ActionListener.class) {
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
/** Returns the timer queue. */
TimerQueue timerQueue() {
return TimerQueue.sharedInstance();
}
public static void setLogTimers(boolean flag) {
logTimers = flag;
}
public static boolean getLogTimers() {
return logTimers;
}
/** Sets the Timer's delay, the number of milliseconds between successive
* <b>actionPerfomed()</b> messages to its listeners
* @see #setInitialDelay
*/
public void setDelay(int delay) {
TimerQueue queue;
if (delay < 0) {
throw new RuntimeException("Invalid initial delay: " + delay);
}
this.delay = delay;
if (isRunning()) {
queue = timerQueue();
queue.removeTimer(this);
cancelEvent();
queue.addTimer(this, System.currentTimeMillis() + delay);
}
}
/** Returns the Timer's delay.
* @see #setDelay
*/
public int getDelay() {
return delay;
}
/** Sets the Timer's initial delay. This will be used for the first
* "ringing" of the Timer only. Subsequent ringings will be spaced
* using the delay property.
* @see #setDelay
*/
public void setInitialDelay(int initialDelay) {
if (initialDelay < 0) {
throw new RuntimeException("Invalid initial delay: " +
initialDelay);
}
this.initialDelay = initialDelay;
}
/** Returns the Timer's initial delay.
* @see #setDelay
*/
public int getInitialDelay() {
return initialDelay;
}
/** If <b>flag</b> is <b>false</b>, instructs the Timer to send
* <b>actionPerformed()</b> to its listeners only once, and then stop.
*/
public void setRepeats(boolean flag) {
repeats = flag;
}
/** Returns <b>true</b> if the Timer will send a <b>actionPerformed()</b>
* message to its listeners multiple times.
* @see #setRepeats
*/
public boolean isRepeats() {
return repeats;
}
/** Sets whether the Timer coalesces multiple pending ActionEvent firings.
* A busy application may not be able
* to keep up with a Timer's message generation, causing multiple
* <b>actionPerformed()</b> message sends to be queued. When processed,
* the application sends these messages one after the other, causing the
* Timer's listeners to receive a sequence of <b>actionPerformed()</b>
* messages with no delay between them. Coalescing avoids this situation
* by reducing multiple pending messages to a single message send. Timers
* coalesce their message sends by default.
*/
public void setCoalesce(boolean flag) {
coalesce = flag;
}
/** Returns <b>true</b> if the Timer coalesces multiple pending
* <b>performCommand()</b> messages.
* @see #setCoalesce
*/
public boolean isCoalesce() {
return coalesce;
}
/** Starts the Timer, causing it to send <b>actionPerformed()</b> messages
* to its listeners.
* @see #stop
*/
public void start() {
timerQueue().addTimer(this, System.currentTimeMillis() + getInitialDelay());
}
/** Returns <b>true</b> if the Timer is running.
* @see #start
*/
public boolean isRunning() {
return timerQueue().containsTimer(this);
}
/** Stops a Timer, causing it to stop sending <b>actionPerformed()</b>
* messages to its Target.
* @see #start
*/
public void stop() {
timerQueue().removeTimer(this);
cancelEvent();
}
/**
* Restarts a Timer, canceling any pending firings, and causing
* it to fire with its initial dely.
*/
public void restart() {
stop();
start();
}
synchronized void cancelEvent() {
eventQueued = false;
}
synchronized void post() {
if (eventQueued == false) {
eventQueued = true;
SwingUtilities.invokeLater(doPostEvent);
}
}
}